package com.jiuyou.websocket.manager;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.serializer.SerializerFeature;
import com.jiuyou.websocket.enums.RequestType;
import com.jiuyou.websocket.service.base.BaseService;
import com.jiuyou.websocket.util.DateTimeUtil;
import com.ruoyi.chat.domain.ChatLast;
import com.ruoyi.wechat.service.WeChatMessageService;
import org.apache.commons.lang3.StringUtils;
import org.joda.time.DateTime;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Service;
import org.springframework.web.socket.TextMessage;
import org.springframework.web.socket.WebSocketSession;

import java.io.IOException;
import java.util.Date;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

/**
 * websocket管理器
 */

public class WebSocketSessionManager extends BaseService {

    private final Logger log = LoggerFactory.getLogger(this.getClass());

    @Autowired
    private WeChatMessageService messageService;
    /**
     * 客户端在线数
     */
    private static int onlineCount = 0;

    /**
     * 存放所有在线的客户端 key：sessionId，value：WebSocket客户端session
     */
    private static final Map<String, WebSocketSession> clientMap = new ConcurrentHashMap<>();

    /**
     * 存放登录用户 key：userId，value：WebSocket客户端session
     */
    private static final Map<String, WebSocketSession> userClientMap = new ConcurrentHashMap<>();
    /**
     * 用户上次发送世家你
     */
    private static final Map<String, Date> lastSendTime = new ConcurrentHashMap<>();

    /**
     * 获取在线客户端数量
     */
    public synchronized int getOnlineCount() {
        return onlineCount;
    }

    /**
     * 添加线上链接的客户端数量
     */
    public synchronized void addOnlineCount() {
        onlineCount++;
    }

    /**
     * 客户端下载是调用将在线数量减1
     */
    public synchronized void subOnlineCount() {
        onlineCount--;
    }


    public void addClientMap(String key, WebSocketSession value){
        clientMap.put(key, value);
    }

    public Map<String, WebSocketSession> getClientMap(){
        return clientMap;
    }

    public void removeClientMap(String key){
        clientMap.remove(key);
    }

    public boolean containsClientMap(String key){
        return clientMap.containsKey(key);
    }


    public void addUserClient(String key, WebSocketSession value){
        addClientMap(value.getId(), value);
        userClientMap.put(key, value);
    }

    public void removeUserClient(String key){
        userClientMap.remove(key);
    }

    public WebSocketSession getUserClientValue(String key){
        return StringUtils.isBlank(key) ? null : userClientMap.get(key);
    }

    public Map<String, WebSocketSession> getUserClientMap(){
        return userClientMap;
    }

    public boolean containsUserClient(String key){
        return userClientMap.containsKey(key);
    }


    /**
     * 移除连接的客户端
     */
    public void removeClient(WebSocketSession wsSession){
        removeClientMap(wsSession.getId());
        String userKey=getUserKey(wsSession);
        removeUserClient(userKey);

    }


    /**
     * 群发消息: 给在线的所有人发消息
     *
     * @param message 消息内容
     */
    public void sendMsgAll(String message) throws IOException {
        log.info("群发消息：{}", message);
        for (Map.Entry<String, WebSocketSession> sessionEntry : clientMap.entrySet()) {
            TextMessage textMessage = new TextMessage(message);
            WebSocketSession wsSession = sessionEntry.getValue();
            wsSession.sendMessage(textMessage);
        }
    }
    public void sendMsgAll(JSONObject jsonObject) throws IOException {
        jsonObject.put("sendDateTime", DateTimeUtil.toDateTimeString(new DateTime()));
        sendMsgAll(JSON.toJSONString(jsonObject, SerializerFeature.WriteMapNullValue));
    }


    /**
     * 指定发送
     */
    public void appointSending(WebSocketSession wsSession, String message){
        try {
//            log.info("发送消息：{}", message);
            wsSession.sendMessage(new TextMessage(message));
        }catch (Exception e){
            e.printStackTrace();
        }
    }
    public void onAppHide(String userKey){

        WebSocketSession wsSession=userClientMap.get(userKey);
        wsSession.getAttributes().put(RequestType.APP_HIDE_FLAG.getValue(),true);
        lastSendTime.remove(userKey);
    }
    public void onAppShow(String userKey){
        WebSocketSession wsSession=userClientMap.get(userKey);
        wsSession.getAttributes().put(RequestType.APP_HIDE_FLAG.getValue(),false);
    }

    public void appointSendingUser(String userKey, JSONObject jsonObject,ChatLast chatLast){
        try {
            boolean needSend=false;
            if (userClientMap.containsKey(userKey)) {
                String message = JSON.toJSONString(jsonObject, SerializerFeature.WriteMapNullValue);
                log.info("发送消息：{}", message);
                TextMessage textMessage = new TextMessage(message);
                WebSocketSession wsSession=userClientMap.get(userKey);
                wsSession.sendMessage(textMessage);
                //在线 看是否隐藏，隐藏则发
                Boolean appHideFlag= (Boolean) wsSession.getAttributes().get(RequestType.APP_HIDE_FLAG.getValue());
                if(null==appHideFlag||appHideFlag){
                    //需要发送消息
                    needSend=true;
                }
            }else{
                //不在线需要发
                needSend=true;
            }

            if(needSend){
                //需要发送消息模板提醒 看5分钟内是否提醒过，超过5分钟的才提醒
                Date lastTime=lastSendTime.get(userKey);
                if(null==lastTime||lastTime.compareTo(new Date(new Date().getTime()-5L*1000*60))<0){
                    String[] userKeyArr= userKey.split("_");
                    String platform=userKeyArr[0];
                    Long userid=Long.valueOf(userKeyArr[1]);
                    if("customer".equals(platform)){
                        // 给用户userid发送模板消息 使用代理人给用户发消息时发送提醒
                        messageService.answer(chatLast);

                    }
                    if("store".equals(platform)){
                        //给代理人userid发送模板消息  使用用户给代理人发消息时发送提醒
                        messageService.question(chatLast);

                    }
                    //设置上次发送时间
                    lastSendTime.put(userKey,new Date());
                }


            }else{
                lastSendTime.remove(userKey);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }


    /**
     * 设置参数推送消息
     */
    public void sendForward(String userKey, RequestType requestType, JSONObject jsonInfo, ChatLast chatLast){
        appointSendingUser(userKey, getParamObj(requestType, jsonInfo),chatLast);
    }

    public void sendForward(WebSocketSession wsSession, RequestType requestType, JSONObject jsonInfo){
        JSONObject jsonObject = getParamObj(requestType, jsonInfo);
        appointSending(wsSession, JSON.toJSONString(jsonObject, SerializerFeature.WriteMapNullValue));
    }
    private JSONObject getParamObj(RequestType requestType, JSONObject jsonInfo){
        JSONObject jsonObject = new JSONObject();
        jsonObject.put("reqType", requestType.getValue());
        jsonObject.put("info", jsonInfo);
        return jsonObject;
    }

}
